package com.pingan.haofang.searchcloud.indexdatasource.service.impl;

import java.util.Date;
import java.util.List;
import java.util.Optional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.pingan.haofang.searchcloud.common.constants.Status;
import com.pingan.haofang.searchcloud.common.dto.OperationResult;
import com.pingan.haofang.searchcloud.index.constants.IndexBuildRunType;
import com.pingan.haofang.searchcloud.index.constants.IndexBuildStatus;
import com.pingan.haofang.searchcloud.index.constants.IndexBuildType;
import com.pingan.haofang.searchcloud.index.domain.Index;
import com.pingan.haofang.searchcloud.index.dto.IndexBuildProgressDTO;
import com.pingan.haofang.searchcloud.index.dto.IndexExecutionDTO;
import com.pingan.haofang.searchcloud.index.service.IndexBuildProgressService;
import com.pingan.haofang.searchcloud.index.service.IndexBuildService;
import com.pingan.haofang.searchcloud.indexdatasource.dao.IndexDatasourceDao;
import com.pingan.haofang.searchcloud.indexdatasource.domain.IndexDatasource;
import com.pingan.haofang.searchcloud.indexdatasource.dto.IndexDatasourceScheduleImportDTO;
import com.pingan.haofang.searchcloud.indexdatasource.service.IndexDatasourceScheduleService;
import com.pingan.haofang.searchcloud.quartz.service.IndexBuildScheduleTaskService;
import com.pingan.haofang.searchcloud.user.domain.SearchProject;

/**
 * 索引构建调度Service实现
 *
 * @author baojie371
 * @date 17/5/15
 * @since 1.0.0
 */
@Service
public class IndexDatasourceScheduleServiceImpl implements IndexDatasourceScheduleService {

    @Autowired
    private IndexDatasourceDao indexDatasourceDao;

    @Autowired
    private IndexBuildService indexBuildService;

    @Autowired
    private IndexBuildProgressService indexBuildProgressService;

    @Autowired
    private IndexBuildScheduleTaskService indexBuildScheduleTaskService;

    @Override
    public OperationResult importDatasource(SearchProject searchProject, Index index,
                                            IndexDatasource indexDatasource, IndexBuildProgressDTO progressDTO) {

        return executeIndexBuild(searchProject, index, indexDatasource, progressDTO);
    }

    @Override
    public IndexBuildProgressDTO updateProgress(IndexDatasourceScheduleImportDTO dto, SearchProject searchProject,
                                                Index index, IndexDatasource indexDatasource) {

        IndexBuildProgressDTO progressDTO = new IndexBuildProgressDTO();
        progressDTO.setIndexName(index.getIndexName());
        progressDTO.setDatasourceName(Optional.ofNullable(indexDatasource)
                .map(IndexDatasource::getName)
                .orElse(null));
        progressDTO.setIndexBuildType(IndexBuildType.FULL.value);
        progressDTO.setProjectCode(searchProject.getProjectCode());
        progressDTO.setRunType(IndexBuildRunType.HANDING.value);
        if (indexDatasource != null) {
            progressDTO.setConfigSnapshot(JSON.toJSONString(indexDatasource));
        } else {
            List<IndexDatasource> datasources = indexDatasourceDao.findByIndexId(index.getId(),
                    Status.NORMAL.getValue());
            progressDTO.setConfigSnapshot(JSON.toJSONString(datasources));
        }
        progressDTO.setStartTime(new Date());
        progressDTO.setStatus(IndexBuildStatus.TODO.value);

        indexBuildProgressService.updateProgress(progressDTO);

        return progressDTO;
    }

    private OperationResult executeIndexBuild(SearchProject searchProject, Index index,
                                              IndexDatasource indexDatasource, IndexBuildProgressDTO progressDTO) {

        if (indexBuildService.checkLock(searchProject.getProjectCode(), index.getIndexName())) {
            return OperationResult.of(false, "该索引当前有任务正在执行中");
        }

        IndexExecutionDTO dto = new IndexExecutionDTO();
        dto.setProjectCode(searchProject.getProjectCode());
        dto.setIndexName(index.getIndexName());
        Optional.ofNullable(indexDatasource).ifPresent(source -> dto.setDataSourceName(source.getName()));

        dto.setProgressId(progressDTO.getId());

        indexBuildScheduleTaskService.doProcess(dto);

        return OperationResult.of(true, "");
    }
}
